/*******************************************************************************
GScene.h

	Author:		LiuDingXi
	e-mail:		liudx@gmail.com
	Date time:	2009-08-07

	Copyright (C) 2009
	All rights reserved.
	
*******************************************************************************/

#ifndef _GSCENE_H_
#define _GSCENE_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "GEngine.h"
#include "GameDC.h"
#include "FileMap.h"
#include "SceneDat.h"
using namespace SceneDat;

// ProcMsg Return Value
enum PMRV {PM_PASS, PM_HOLD, PM_NEXT};

class GSight;

class GObject
{
public:
	GObject();
	virtual ~GObject();

	virtual void SetPos(int x, int y);
	virtual void OnDraw(GDC* pDC) = 0;

	virtual BOOL GetPos(POS& refPos)const = 0;
	virtual BOOL GetBox(BOX& refBox)const = 0;
	virtual BOOL GetCxy(CXY& refCxy)const = 0;

	virtual void Update(UINT nMillisecond) = 0;

	virtual PMRV ProcMsg(GMsg& refMsg) {return PM_PASS;}

	virtual BOOL DataBind(GSight* pSight, const BYTE* pBase, SceneDat::PTR ptr) = 0;

	virtual bool IsVisible()const;
	virtual bool SetVisible(bool bVisible);

protected:
	int		m_nPosX;
	int		m_nPosY;
	bool	m_bVisible;
};

typedef const STYLE*	GPStyle;

class GSight : public CFileMap
{
	friend class GScene;
	friend class CGame;
public:
	GSight();
	virtual ~GSight();
	
public:
	virtual BOOL Init(LPCTSTR szFolder, GDC* pDC);

	//virtual bool Load(const BYTE* pData, UINT nSize);
	virtual bool Load(LPCTSTR szFilePath, LPTSTR pFile);
	virtual void Free();
	
public:
	bool	HasLoaded()const;
	bool	HasInited()const;

	int		GetMapCount()const;
	int		GetSpriteCount()const;
	int		GetDialogCount()const;
	
	BOOL	InitDialog(GDialog* pDialog, UINT nID);
	
	GImage*	GetImage(int nId)const;

	GPStyle GetStyle(int nId)const;

protected:
	GMap*		m_pMaps;
	GSprite*	m_pSprites;

protected:
	GImage*		m_pImages;
	GDialog*	m_pDialogs;
	
	friend class GScene;
};


class GScene : public CFileMap
{
public:
	GScene();
	virtual ~GScene();
	
public:
	virtual BOOL Init(LPCTSTR szFolder, GDC* pDC, GEngine* pEngine);

	//virtual bool Load(const BYTE* pData, UINT nSize);
	virtual bool Load(LPCTSTR szFilePath, LPTSTR pFile);
	virtual void Free();

	virtual bool IsVisible()const;
	virtual void OnDraw(GDC* pDC);
	virtual PMRV ProcMsg(GMsg& refMsg);

	// Update would return quit code
	// 0  don't quit
	// > 0 quit with scene id
	// < 0 quit 

	virtual LONG Update(UINT nMillisecond); 

public:
	// call by GDialog
	BOOL	InitDialog(GDialog* pDialog, UINT nID);

	SINT	LoadSights(SINT nDelay, LPCTSTR szFilePath, LPTSTR pFile);
	SINT	InitSights(SINT nDelay, LPCTSTR szFolder, GDC* pDC);

	BOOL	NeedLoadMore()const;

	BOOL	CheckReady(SINT nCount, const SINT* pItems)const;

	GSprite*	GetSprite(SINT iSprite);

protected:
	GEngine*	m_pEngine;
	
	GSight*		m_pSights;

	SINT		m_nUnload;
	SINT		m_nUninit;

	GMap*		GetMap(SINT iMap);

public:
	enum {eMap, eSprite, eDialog};

	struct VNODE
	{
		GObject*	pObject;
		UINT		nType;
		VNODE*		pPrev;
		VNODE*		pNext;
	};

protected:

	VNODE*		m_pHead;
	VNODE*		m_pTail;
	VNODE*		m_pTemp;

public:
	
	VNODE*		AddHead(GObject* pObject, UINT nType);
	VNODE*		AddTail(GObject* pObject, UINT nType);
	VNODE*		Find(GObject* pObject, BOOL bHead = FALSE);
	GObject*	Remove(VNODE* pNode);

	VNODE*		RemoveTail(GObject* pObject);
	VNODE*		RemoveHead(GObject* pObject);

};


#endif//_GSCENE_H_
